package com.dream.oauth2.security;

import com.dream.oauth2.model.entity.OAuth2UserInfo;
import com.dream.oauth2.model.entity.User;
import com.dream.oauth2.repository.OAuth2UserInfoRepository;
import com.dream.oauth2.service.UserService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    private final OAuth2UserInfoRepository oauth2UserInfoRepository;
    private final UserService userService;

    public LoginSuccessHandler(OAuth2UserInfoRepository oauth2UserInfoRepository, UserService userService) {
        this.oauth2UserInfoRepository = oauth2UserInfoRepository;
        this.userService = userService;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                      Authentication authentication) throws IOException, ServletException {
        log.info("登录成功，principal: {}", authentication.getPrincipal());

        HttpSession session = request.getSession();
        String requestURI = request.getRequestURI();

        // 处理用户名密码登录
        if (authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            User user = userService.findByUsername(userDetails.getUsername());


            // 检查用户是否已存在
            OAuth2UserInfo userInfo = oauth2UserInfoRepository.findByProviderAndProviderUserId("system", user.getUsername())
                    .orElse(null);
            if (null == userInfo) {
                // 创建OAuth2UserInfo对象
                userInfo = new OAuth2UserInfo();
            }
            userInfo.setProvider("system");
            userInfo.setProviderUserId(user.getUsername());
            userInfo.setUsername(user.getUsername());
            userInfo.setNickname(user.getNickname());
            userInfo.setEmail(user.getEmail());
            userInfo.setCreateTime(LocalDateTime.now());
            userInfo.setUpdateTime(LocalDateTime.now());

            // 保存用户信息
            oauth2UserInfoRepository.save(userInfo);
            
            // 设置session
            session.setAttribute("user", userInfo);
            response.sendRedirect("/auth/index.html");
            return;
        }

        // 处理OAuth2登录
        if (authentication.getPrincipal() instanceof OAuth2User) {
            OAuth2User oauth2User = (OAuth2User) authentication.getPrincipal();
            Map<String, Object> attributes = oauth2User.getAttributes();

            // 从请求URI中获取认证提供商
            String provider = getProviderFromRequestURI(requestURI);
            log.info("认证提供商: {}", provider);

            // 获取用户ID
            String providerUserId = getProviderUserId(provider, attributes);
            log.info("提供商用户ID: {}", providerUserId);

            // 检查用户是否已存在
            OAuth2UserInfo existingUser = oauth2UserInfoRepository.findByProviderAndProviderUserId(provider, providerUserId)
                .orElse(null);
            if (existingUser == null) {
                // 创建新用户
                OAuth2UserInfo newUser = createOAuth2UserInfo(provider, providerUserId, attributes);
                oauth2UserInfoRepository.save(newUser);
                session.setAttribute("user", newUser);
            } else {
                // 更新现有用户信息
                updateOAuth2UserInfo(existingUser, attributes);
                oauth2UserInfoRepository.save(existingUser);
                session.setAttribute("user", existingUser);
            }

            response.sendRedirect("/auth/index.html");
        } else {
            log.error("不支持的认证类型");
            response.sendRedirect("/login.html?error=true");
        }
    }

    private String getProviderFromRequestURI(String requestURI) {
        if (requestURI.contains("/login/oauth2/code/github")) {
            return "github";
        } else if (requestURI.contains("/login/oauth2/code/gitee")) {
            return "gitee";
        } else if (requestURI.contains("/login/oauth2/code/qq")) {
            return "qq";
        }
        throw new IllegalArgumentException("不支持的认证提供商");
    }

    private String getProviderUserId(String provider, Map<String, Object> attributes) {
        return switch (provider) {
            case "github" -> attributes.get("id").toString();
            case "gitee" -> attributes.get("id").toString();
            case "qq" -> attributes.get("openid").toString();
            default -> throw new IllegalArgumentException("不支持的认证提供商");
        };
    }

    private OAuth2UserInfo createOAuth2UserInfo(String provider, String providerUserId, Map<String, Object> attributes) {
        OAuth2UserInfo userInfo = new OAuth2UserInfo();
        userInfo.setProvider(provider);
        userInfo.setProviderUserId(providerUserId);
        userInfo.setUsername(getUsername(provider, attributes));
        userInfo.setNickname(getNickname(provider, attributes));
        userInfo.setEmail(getEmail(provider, attributes));
        userInfo.setAvatar(getAvatar(provider, attributes));
        userInfo.setCreateTime(LocalDateTime.now());
        userInfo.setUpdateTime(LocalDateTime.now());
        return userInfo;
    }

    private void updateOAuth2UserInfo(OAuth2UserInfo userInfo, Map<String, Object> attributes) {
        userInfo.setUsername(getUsername(userInfo.getProvider(), attributes));
        userInfo.setNickname(getNickname(userInfo.getProvider(), attributes));
        userInfo.setEmail(getEmail(userInfo.getProvider(), attributes));
        userInfo.setAvatar(getAvatar(userInfo.getProvider(), attributes));
        userInfo.setUpdateTime(LocalDateTime.now());
    }

    private String getUsername(String provider, Map<String, Object> attributes) {
        return switch (provider) {
            case "github" -> (String) attributes.get("login");
            case "gitee" -> (String) attributes.get("login");
            case "qq" -> (String) attributes.get("nickname");
            default -> throw new IllegalArgumentException("不支持的认证提供商");
        };
    }

    private String getNickname(String provider, Map<String, Object> attributes) {
        return switch (provider) {
            case "github" -> (String) attributes.get("name");
            case "gitee" -> (String) attributes.get("name");
            case "qq" -> (String) attributes.get("nickname");
            default -> throw new IllegalArgumentException("不支持的认证提供商");
        };
    }

    private String getEmail(String provider, Map<String, Object> attributes) {
        return switch (provider) {
            case "github" -> (String) attributes.get("email");
            case "gitee" -> (String) attributes.get("email");
            case "qq" -> (String) attributes.get("email");
            default -> null;
        };
    }

    private String getAvatar(String provider, Map<String, Object> attributes) {
        return switch (provider) {
            case "github" -> (String) attributes.get("avatar_url");
            case "gitee" -> (String) attributes.get("avatar_url");
            case "qq" -> (String) attributes.get("figureurl_qq_2");
            default -> null;
        };
    }
}